package br.eng.eliseu.gwt.gestaoWeb.client.ui.core;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import br.eng.eliseu.gwt.gestaoWeb.client.util.DateUtilClient;
import br.eng.eliseu.gwt.gestaoWeb.client.util.ListBoxUtil;
import br.eng.eliseu.gwt.gestaoWeb.model.pessoa.PessoaDocumento;
import br.eng.eliseu.gwt.gestaoWeb.model.pessoa.PessoaFone;
import br.eng.eliseu.gwt.gestaoWeb.model.pessoa.TipoDocumentoEnum;
import br.eng.eliseu.gwt.gestaoWeb.model.pessoa.TipoFoneEnum;
import br.eng.eliseu.gwt.gestaoWeb.model.pessoa.TipoSexoEnum;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;

public class PessoaView extends Composite {

	private static PessoaViewUiBinder uiBinder = GWT.create(PessoaViewUiBinder.class);
	interface PessoaViewUiBinder extends UiBinder<Widget, PessoaView> {	}
	
	@UiField AbsolutePanel pessoaPanel;
	@UiField TextBox nomeTBox;
	@UiField DateBox nascimentoTBox;
	@UiField (provided = true) ValueListBox<TipoSexoEnum> sexoLBox;
	@UiField ListBox documentoLBox;
	@UiField Button novoDocButton;
	@UiField Button excluiDocButton;
	@UiField ListBox foneLBox;
	@UiField Button novoFoneButton;
	@UiField Button excluiFoneButton;
	
	@UiField AbsolutePanel documentoPanel;
	@UiField Label msgDocLabel;
	@UiField ListBox tipoDocumentoLBox;
	@UiField TextBox documentoTBox;
	@UiField TextBox emissorTBox;
	@UiField DateBox emissaoTBox;
	@UiField DateBox validadeTBox;
	@UiField DateBox primeiraViaTBox;
	@UiField Button salvaDocButton;
	@UiField Button cancelaDocButton;
	
	@UiField AbsolutePanel fonePanel;
	@UiField Label msgFoneLabel;
	@UiField ListBox tipoFoneLBox;
	@UiField TextBox foneTBox;
	@UiField CheckBox principalFoneCBox;
	@UiField Button salvaFoneButton;
	@UiField Button cancelaFoneButton;

	private final DialogBox dlg = new DialogBox();

	private List<PessoaDocumento> docList = new ArrayList<PessoaDocumento>();
	private PessoaDocumento docSelecionado;
	
	private List<PessoaFone> foneList = new ArrayList<PessoaFone>();
	private PessoaFone foneSelecionado;
	
	public PessoaView() {
		sexoLBox = new ValueListBox<TipoSexoEnum>(new Renderer<TipoSexoEnum>() {
			public String render(TipoSexoEnum sexo) {
				String s = "";
				if (sexo != null) {
					s = sexo.getNome();
				}
				return s;
			}

			public void render(TipoSexoEnum sexo, Appendable appendable) throws IOException {
				String s = render(sexo);
				appendable.append(s);
			}
		});

		initWidget(uiBinder.createAndBindUi(this));
//		cpfTBox.setMask("999.999.999-99");
		nascimentoTBox.setFormat( DateUtilClient.getDateFormat() );
		populaTipoSexoLBox();

		
		documentoPanel.setVisible(false);
		showMessage(msgDocLabel, "", false);
		ListBoxUtil.populate(tipoDocumentoLBox, true, TipoDocumentoEnum.values());
		
		fonePanel.setVisible(false);
		showMessage(msgFoneLabel, "", false);
		ListBoxUtil.populate(tipoFoneLBox, true, TipoFoneEnum.values());
	}

	public String getNome(){
		if (nomeTBox!=null && !"".equals(nomeTBox.getValue())){
			return nomeTBox.getValue();
		} else {
			return "";
		}
	}
	public void setNome(String nome) {
		if (nome==null){
			nome = "";
		}
		this.nomeTBox.setValue(nome);
	}


	public Date getNascimento() {
		if (nascimentoTBox!=null && !"".equals(nascimentoTBox.getValue())){
			return nascimentoTBox.getValue();
		}
		return new Date();
	}
	public void setNascimento(Date dtNascimento) {
		if ( dtNascimento==null){
			dtNascimento = new Date();
		}
		this.nascimentoTBox.setValue(dtNascimento);
	}

	private void populaTipoSexoLBox() {
		List<TipoSexoEnum> list = new ArrayList<TipoSexoEnum>(Arrays.asList(TipoSexoEnum.values()));
		sexoLBox.setAcceptableValues(list);
	}
//	public void setTipoSexo(String sexo) {
//		if (sexo!=null){
//			if ("".equals(sexo)){
//				sexoLBox.setValue(null);
//			} else {
//				TipoSexoEnum s;
//				s.
////				tl.setNome(sexo);
////				int i = Collections.binarySearch(tipoLogradouroList, tl, comparatorTipoLogradouro);
//				sexoLBox.setValue(tl);
//			}
//		}
//	}
	public void setTipoSexo(TipoSexoEnum sexo) {
		if (sexo!=null){
			sexoLBox.setValue(sexo);
		}
	}
	public String getTipoSexoItem(){
		if (sexoLBox.getValue()!=null){
			return sexoLBox.getValue().getNome();
		} else {
			return "";
		}
	}
	public TipoSexoEnum getTipoSexo(){
		return sexoLBox.getValue();
	}
	
	public List<PessoaDocumento> getDocumentoList() {
		return docList;
	}
	public void setDocumentoList(List<PessoaDocumento> documentoList) {
		this.docList = documentoList;
		populaDocumentoLBox(documentoList);
	}
	
	public List<PessoaFone> getFoneList() {
		return foneList;
	}
	public void setFoneList(List<PessoaFone> foneList) {
		this.foneList = foneList;
		populaFoneLBox(foneList);
	}

	
	
	@UiHandler("novoDocButton")
	void onNovoDocButtonClick(ClickEvent event) {
		limpaDocumentosView();
		docSelecionado = null;
		openDlg(documentoPanel, "Novo de Documentos");
	}
	@UiHandler("documentoLBox")
	void onDocumentoLBoxDoubleClick(DoubleClickEvent event) {
		limpaDocumentosView();
		docSelecionado = (PessoaDocumento) ListBoxUtil.getItemSelected(documentoLBox, docList);
		populaDocumentosView(docSelecionado);
		openDlg(documentoPanel, "Editor de Documentos");
	}
	@UiHandler("excluiDocButton")
	void onExcluiDocButtonClick(ClickEvent event) {
		docSelecionado = (PessoaDocumento) ListBoxUtil.getItemSelected(documentoLBox, docList);
		for (PessoaDocumento e : docList) {
			if (e.equals(docSelecionado)){
				docList.remove(e);
				break;
			}
		}
		populaDocumentoLBox(docList);
	}
	@UiHandler("salvaDocButton")
	void onSalvaDocButtonClick(ClickEvent event) {
		if ( checaCampoEmBrancoDocumentoView() ){
			if(docSelecionado==null){
				// --- Novo Documento
				docSelecionado = pegaDocumentoView();
				docList.add(docSelecionado);
			} else {
				// --- Documento Editado
				docList.set(docList.indexOf(docSelecionado), pegaDocumentoView());
			}
			populaDocumentoLBox(docList);
			dlg.hide();
		}
	}
	@UiHandler("cancelaDocButton")
	void onCancelaDocButtonClick(ClickEvent event) {
		dlg.hide();
	}
	
	
	
	@UiHandler("novoFoneButton")
	void onNovoFoneButtonClick(ClickEvent event) {
		limpaFoneView();
		foneSelecionado = null;
		openDlg(fonePanel, "Editor de Telefone");
	}
	@UiHandler("foneLBox")
	void onFoneLBoxDoubleClick(DoubleClickEvent event) {
		limpaFoneView();
		foneSelecionado = (PessoaFone) ListBoxUtil.getItemSelected(foneLBox, foneList);
		populaFoneView(foneSelecionado);
		openDlg(fonePanel, "Editor de Telefones");
	}
	@UiHandler("excluiFoneButton")
	void onExcluiFoneButtonClick(ClickEvent event) {
		foneSelecionado = (PessoaFone) ListBoxUtil.getItemSelected(foneLBox, foneList);
		for (PessoaFone f : foneList) {
			if (f.equals(foneSelecionado)){
				foneList.remove(f);
				break;
			}
		}
		populaFoneLBox(foneList);
	}
	@UiHandler("salvaFoneButton")
	void onSalvaFoneButtonClick(ClickEvent event) {
		if ( checaCampoEmBrancoFoneView() ){
			if(foneSelecionado==null){
				// --- Novo Fone
				foneSelecionado = pegaFoneView();
				foneList.add(foneSelecionado);
			} else {
				// --- Fone Editado
				foneList.set(foneList.indexOf(foneSelecionado), pegaFoneView());
			}
			populaFoneLBox(foneList);
			dlg.hide();
		}
	}
	@UiHandler("cancelaFoneButton")
	void onCancelaFoneButtonClick(ClickEvent event) {
		dlg.hide();
	}
	
	private void openDlg( Widget w, String titulo ){
		showMessage(msgDocLabel, "", false);
		showMessage(msgFoneLabel, "", false);
		dlg.setGlassEnabled(true); // -- Deixa o fundo desabilitado fosco
		dlg.setModal(false); 
		dlg.setText(titulo);
		w.setVisible(true);
		dlg.setWidget(w);
		dlg.center();
		dlg.show();
	}
	
	private void showMessage( Label caixa, String msg, Boolean exibe ){
		caixa.setVisible(exibe);
		if ( exibe ){
			caixa.setText(msg);
		}
	}

	private void populaDocumentoLBox( List<PessoaDocumento> docList ){
		documentoLBox.clear();
		for (PessoaDocumento d : docList) {
			documentoLBox.addItem(d.toString(), d.getChave());
		}
	}
	
	private void populaFoneLBox( List<PessoaFone> foneList ){
		foneLBox.clear();
		for (PessoaFone d : foneList) {
			foneLBox.addItem(d.toString(), d.getChave());
		}
	}
	
	/* Views das Dlgs
	 * -- Documento
	 */
	private void limpaDocumentosView(){
		tipoDocumentoLBox.setSelectedIndex(-1);
		documentoTBox.setValue("");
		emissorTBox.setValue("");
		emissaoTBox.setValue(null);
		validadeTBox.setValue(null);
		primeiraViaTBox.setValue(null);
	}
	
	private void populaDocumentosView( PessoaDocumento d ){
		if ( d!=null){
			ListBoxUtil.setItemSelected(tipoDocumentoLBox, d.getTipoDocumento().name());
			documentoTBox.setValue(d.getDocumento());
			emissorTBox.setValue(d.getEmissor());
			emissaoTBox.setValue(d.getDtEmissao());
			validadeTBox.setValue(d.getDtValidade());
			primeiraViaTBox.setValue(d.getDtValidade());
		}
	}

	private PessoaDocumento pegaDocumentoView(){
		PessoaDocumento d = new PessoaDocumento();
		
		d.setTipoDocumento((TipoDocumentoEnum) ListBoxUtil.getItemSelected(tipoDocumentoLBox, TipoDocumentoEnum.values()));
		d.setDocumento(documentoTBox.getValue());
		d.setEmissor(emissorTBox.getValue());
		d.setDtEmissao(emissaoTBox.getValue());
		d.setDtValidade(validadeTBox.getValue());
		d.setDtPrimeiraVia(primeiraViaTBox.getValue());
		
		return d;
	}
	
	private Boolean checaCampoEmBrancoDocumentoView(){
		if (tipoDocumentoLBox==null || tipoDocumentoLBox.getSelectedIndex()<0 ){
			showMessage(msgDocLabel, "Campo Tipo Documento em Branco", true);
			return false;
		}
		if (documentoTBox==null || "".equals(documentoTBox.getValue()) ){
			showMessage(msgDocLabel, "Campo Documento em Branco", true);
			return false;
		}
		
		return true;
	}

	/* --- Fones
	 */
	private void limpaFoneView(){
		tipoFoneLBox.setSelectedIndex(-1);
		foneTBox.setValue("");
		principalFoneCBox.setValue(false);
	}
	
	private void populaFoneView( PessoaFone f ){
		if ( f!=null){
			ListBoxUtil.setItemSelected(tipoFoneLBox, f.getTipoFone().name());
			foneTBox.setValue(f.getFone());
			principalFoneCBox.setValue(f.getPrincipal());
		}
	}

	private PessoaFone pegaFoneView(){
		PessoaFone f = new PessoaFone();
		
		f.setTipoFone((TipoFoneEnum) ListBoxUtil.getItemSelected(tipoFoneLBox, TipoFoneEnum.values()));
		f.setFone(foneTBox.getValue());
		f.setPrincipal(principalFoneCBox.getValue());
		
		return f;
	}
	
	private Boolean checaCampoEmBrancoFoneView(){
		if (tipoFoneLBox==null || tipoFoneLBox.getSelectedIndex()<0 ){
			showMessage(msgFoneLabel, "Campo Tipo Telefone em Branco", true);
			return false;
		}
		if (foneTBox==null || "".equals(foneTBox.getValue()) ){
			showMessage(msgFoneLabel, "Campo Telefone em Branco", true);
			return false;
		}
		
		return true;
	}

}
